#ifndef STREAM_CONVERT_H
#define STREAM_CONVERT_H

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavcodec/bsf.h>
}

#include <iostream>
#include <fstream>
#include <string>
#include <memory>
#include <vector>
#include <functional>
#include <thread>
#include <atomic>
#include <mutex>
#include "common_media_define.h"
namespace El {
namespace Hal {

class StreamConverter {
    StreamConverter(const StreamConverter &) = delete;
    StreamConverter &operator=(const StreamConverter &) = delete;
    StreamConverter(StreamConverter &&) = delete;
    StreamConverter &operator=(StreamConverter &&) = delete;

public:
    // 单例相关
    static StreamConverter &GetInstance()
    {
        static StreamConverter *instance = nullptr;
        if (instance == nullptr) {
            instance = new StreamConverter();
            std::string input_file = "../resource/h264_25_1M_aac.mp4";
            instance->Open(input_file);
            instance->Start(true);
        }
        return *instance;
    }

    StreamConverter();
    ~StreamConverter();

    bool Open(const std::string &inputFile);

    bool GetVideoInfo(VideoEncFormat &video);

    bool GetAudioInfo(AudioEncFormat &audio);

    // 注册视频回调函数
    bool RegisterVideoCallback(std::function<void(const VideoEncPacket &)> videoCallback);

    // 注册音频回调函数
    bool RegisterAudioCallback(std::function<void(const AudioEncPacket &)> audioCallback);

    // 启动转换
    bool Start(bool loop = false);

    // 停止转换
    void Stop();

    void Close();

private:
    // 处理线程
    void ProcessingLoop();

    // 新增的私有成员函数
    void ProcessVideoPacket(AVPacket *pkt, uint64_t &total_pts);
    void ProcessAudioPacket(AVPacket *pkt, uint64_t &total_pts);

    std::vector<uint8_t> GenerateADTSHeader(int aac_data_length, int sample_rate);

    int GetFrequencyIndex(int sample_rate);

private:
    std::string input_file;
    AVFormatContext *format_ctx_raw = nullptr;
    std::unique_ptr<AVFormatContext, void (*)(AVFormatContext *)> format_ctx;

    // 视频相关
    int32_t video_stream_index = -1;
    const AVCodec *video_codec = nullptr;
    std::unique_ptr<AVCodecContext, void (*)(AVCodecContext *)> video_codec_ctx;
    std::unique_ptr<AVPacket, void (*)(AVPacket *)> video_packet;
    const AVBitStreamFilter *video_bsf = nullptr;
    AVBSFContext *video_bsf_ctx_raw = nullptr;
    std::unique_ptr<AVBSFContext, void (*)(AVBSFContext *)> video_bsf_ctx;

    // 音频相关
    int32_t audio_stream_index = -1;
    const AVCodec *audio_codec = nullptr;
    std::unique_ptr<AVCodecContext, void (*)(AVCodecContext *)> audio_codec_ctx;
    const AVBitStreamFilter *audio_bsf = nullptr;
    AVBSFContext *audio_bsf_ctx_raw = nullptr;
    std::unique_ptr<AVBSFContext, void (*)(AVBSFContext *)> audio_bsf_ctx;

    std::chrono::steady_clock::time_point video_start_time;
    std::chrono::steady_clock::time_point audio_start_time;
    bool is_first_video_frame{true};
    bool is_first_audio_frame{true};

    // 回调函数
    std::function<void(const VideoEncPacket &)> video_callback;
    std::function<void(const AudioEncPacket &)> audio_callback;

    // 线程控制
    std::thread processing_thread;
    std::atomic<bool> is_running{false};
    std::mutex callback_mutex;

    std::atomic<bool> should_loop{false};
};

} // namespace Hal
} // namespace El

#endif // STREAM_CONVERT_H